package org.example.common;

import lombok.extern.slf4j.Slf4j;

/**
 * 字节串工具
 *
 * @author 欧阳劲驰
 * @since JDK1.8
 */
@Slf4j
public class ByteUtil {
    /**
     * crc校验
     *
     * @param data 报文
     * @return crc校验符
     */
    public static String getCRC(String data) {
        int CRC = 0xFFFF;
        int num = 0xA001;
        int inum;
        byte[] sb = data.getBytes();
        for (byte b : sb) {
            inum = b;
            CRC = (CRC >> 8) & 0x00FF;
            CRC ^= inum;
            for (int k = 0; k < 8; k++) {
                int flag = CRC % 2;
                CRC = CRC >> 1;

                if (flag == 1) {
                    CRC = CRC ^ num;
                }
            }
        }
        StringBuilder crc = new StringBuilder(Integer.toHexString(CRC));
        //如果小于4位,则补0
        if (crc.length()<4) {
            for (int i = 0; i <= 4 - crc.length(); i++) {
               crc.insert(0, "0");
            }
        }
        return crc.toString();
    }

    /**
     * 二进制字节码转16进制字符串
     *
     * @param bytes 二进制字节码串
     * @param r     读取长度
     * @return 16进制字符串
     */
    public static String BinaryToHexString(byte[] bytes, int r) {
        //16进制需要的字符串
        String hexStr = "0123456789ABCDEF";
        //返回用的字符串
        StringBuilder result = new StringBuilder();
        String hex;
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            //或略字节码串中初始化的0
            if (i == r) {
                break;
            }
            //高位
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            //低位
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            //将解析的字节字符串拼入返回用的字符串
            result.append(hex);
        }
        return result.toString();
    }

    /**
     * 二进制字节码转字符串
     *
     * @param bytes 二进制字节码串
     * @param r     读取长度
     * @return 字符串
     */
    public static String BinaryToString(byte[] bytes, int r) {
        //从字节数组0至length读取,并返回新字符串
        return new String(bytes, 0, r);
    }

    /**
     * 16进制字符串转字节数组
     *
     * @param hexString 16进制字符串
     * @return 字节数组
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.isEmpty()) {
            return null;
        }
        // toUpperCase将字符串中的所有字符转换为大写
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        // toCharArray将此字符串转换为一个新的字符数组。
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * 字符转字节
     *
     * @param c 字符
     * @return 字节
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

}